#include <vfsystem_a.h>

int         fdcounter=0;
FD*         fdlist[fdlistsize];
MMheap*     Heap;
char        CWD_PATH[PATH];
i_node*     CWD_inode;
i_node*     root;


/*********************************************************************Help functions******************/
void gettime(double* i_time/*mikro sec*/ )
{
    struct       timeval tv_start;
    gettimeofday(&tv_start, NULL);/*mikro second scale*/
    *i_time=time(NULL)*pow(10,6)+tv_start.tv_usec;
}
    /*everyobect will be contained from some  PAGES
    but this part actually  will be insize of MM_Mamager*/
size_t VFS_CalculateAllocSize(size_t _objsize)/*in bytes units*/
{
    size_t allocsize;
    if(I_N_PAGESIZE>=_objsize)
    {
        allocsize=I_N_PAGESIZE;
    }

    else/*it is not ligical if page size will be less than i_node*/
    {
        allocsize=_objsize/I_N_PAGESIZE;
        allocsize+=PAGEREQEST(_objsize%I_N_PAGESIZE);
        allocsize=I_N_PAGESIZE*allocsize;
    }
    return allocsize;
}

i_node* VFS_CreateBaseinodeData(char* name)
{
    size_t             nodesize;
    i_node*            node;
    err_MM             err;

    nodesize=VFS_CalculateAllocSize(sizeof(i_node));
    node=(i_node*) MM_Malloc(Heap,nodesize,&err);/*node size in bytes*/
    if(err)
    {
        return 0;
    }
    node->uid=getuid();
    node->gid=getgid();
    gettime(&(node->atime));
    gettime(&(node->mtime));
    strcpy((node->i_Filename),name);
    return node;
}


/*Creates inderelevels according to provided level*/
inode_Err VFS_Createinderlevels(indPtr* _indPTR,ind_lvl _level)/*its the adress of indPtr*/
{
    err_MM  err;
    size_t  i=0;
    if(_level>0)
    {
    /*I_N_BLOCKS)*sizeof(indPtr)-Has PAGE Size.
    All_indPTR now will be pointer to array of objects, each object is array*/
      *_indPTR=(void*)MM_Malloc(Heap,(I_N_BLOCKS)*sizeof(indPtr),&err);
      for(i=0;i<I_N_BLOCKS; ++i)
      {
          if((VFS_Createinderlevels(&((*_indPTR)[i]),_level-1)))
          {
              return VFS_INDER_LEVEL_CREATION_PROBLEM;
          }

      }
      return 0;
    }

    *_indPTR=(void*)MM_Malloc(Heap,(I_N_BLOCKS)*sizeof(void*),&err);
    for(i=0;i<I_N_BLOCKS;++i)
    {
        (*_indPTR)[i]=0;/*initiallize the data to 0*,every (*_indPTR)[i] has
                            void* level or (i_node*) level*/
    }

    return (inode_Err)err;
}

indPtr VFS_FindFreePTR(indPtr* _indPTR,ind_lvl _level)/*its the adress of indPtr*/
{
    indPtr temp;
    size_t    i=0;

    if(_level==0)/*Works on data level Datalevel*/
    {
        for(i=0;i<I_N_BLOCKS;++i)
        {
            if(!((* _indPTR)[i]) )/*every (*_indPTR)[i] has
         void* level or (i_node*) level*/
            {
                return &((* _indPTR)[i]);
            }
        }
        return 0;/*there are no empty data on this branch Memory*/
    }

    for(i=0;i<I_N_BLOCKS;++i)
    {
        temp=VFS_FindFreePTR(&((*_indPTR)[i]),_level-1);/*To down by one level*/
        if(temp==0)/*If temp==0 the empty cell will be in next block*/
        {
            continue;
        }
        if (!*temp)
        {
            return temp;/*adress or pointer to void* ore i_node*/
        }
    }
    printf("There are no free space!!!!!!!!!!\n");
    return 0/*ALl possible levels was filled, any data can't be added */;
}

indPtr VFS_FindInderlevel2Insert(I_Block* _blk)
{
    indPtr    ptr=0;
    size_t          i;/* I want to find Inder pointer which i can use to connect with it*/

   for(i=0;i<I_N_LEVELS;++i)/*From direct to tripple undirect*/
   {
       /*If one of N_directArr[i] which !=0 i have to check the empty
       PTR if it is not exist i need to incremetn i*/
       if((_blk->N_directArr)[i])
       {
           ptr=VFS_FindFreePTR(&(_blk->N_directArr[i]),i);/*Recurcivey checks if exist empty
                                                          pointers at given INDERECTION LEVEL*/
           if(ptr)
            {
                return ptr;/*Local*/
            }
       }
       else /*if level not exist  i need to create it*/
       {
           VFS_Createinderlevels(&((_blk->N_directArr)[i]),i);/*I send pointer to indPtr*/
           ptr=VFS_FindFreePTR(&((_blk->N_directArr)[i]),i);
           return ptr;
       }
   }
   return 0; /* all aviable  levels is occupied*/
}

inode_Err VFS_Insert2Parent(I_Block* _blck,i_node** _node)
{
     indPtr ptr=VFS_FindInderlevel2Insert(_blck);/*This function has to return the poiter inside to which node able to be connected to connenct thei_node*/
     if(ptr==0)
     {
         return VFS_ALL_PLACES_IN_DIRECTORY_FILLED;
     }
    *ptr=*_node;/*(Void* pointer)*/
    return 0;
}

inode_Err VFS_InitInderLevels(indPtr* _N_directArr,i_node* _parnt,i_node* _node)
{
    size_t          i;
    err_MM          err;
   _N_directArr[0]=(void*)MM_Malloc(Heap,I_N_BLOCKS*sizeof(void*),&err);
   if(err)
   {
       return VFS_INDER_LEVEL_CREATION_PROBLEM;
   }
   (_N_directArr[0])[0]=_parnt;
   (_N_directArr[0])[1]=_node;

   for(i=2;i<I_N_BLOCKS;++i)
   {
       (_N_directArr[0])[i]=0;
   }


    for(i=1; i<I_N_LEVELS;++i)
    {
        (_N_directArr)[i]=0;
    }
    return 0;
}

inode_Err VFS_I_Blockcreate(i_node* _parnt,i_node* _node,i_mode _mode)
{
    err_MM          err;
    inode_Err       err1;
    size_t          iBlocksize= VFS_CalculateAllocSize(sizeof(I_Block));
    size_t          i;

    _node->i_n_blk=(I_Block*)MM_Malloc(Heap,iBlocksize,&err);
    if(err)
    {
        return  VFS_BLOCK_CREATION_PROBLEMS;
    }
    /*update inderection level inside of N_directArr*/
    _node->i_n_blk->Link_count=1;
    if(VFS_DERECTORY==_mode)
    {
        if((err1=VFS_InitInderLevels((void***)(_node->i_n_blk-> N_directArr),_parnt,_node)))
        {
            return err1;
        }

    _node->i_n_blk->numofptr=2;
    /*There are  2 difined pointers for each Directory to  itself and parent*/
    _node->i_n_blk->sizeData=(_node->i_n_blk->numofptr)*sizeof(i_node*) ;
    }
    else
    {

        for(i=0; i<I_N_LEVELS;++i)
        {
            (_node->i_n_blk-> N_directArr)[i]=0;/*initiallizing of level for i_nodes not Directories*/
        }
        _node->i_n_blk->numofptr=0;
        _node->i_n_blk->sizeData=0;
    }
    return 0;
}

inode_Err VFS_UpdateParentDirectory(i_node*_parnt)
{
    ++_parnt->i_n_blk->numofptr;
    _parnt->i_n_blk->sizeData+=sizeof(void*);
    return 0;
}

i_node* VFS_CreateInodes(char* _name,i_mode _mode,i_node* _parnt,inode_Err* err1)
{
    i_node*         node;
    if(_name==0)
    {
        return 0;
    }
    if( 0>_mode || _mode>5)/*only these _mode are legal*/
    {
        return 0;
    }
    node=VFS_CreateBaseinodeData(_name);
    node->mode=_mode;
    node->permision=0xFFFF;
    if(_mode!=VFS_HLINK)
    {
        if((*err1=VFS_I_Blockcreate(_parnt,node,_mode)))
        {
            return 0;
        }
    }
    return node;
}

i_node* VFS_PATHpreparing(char* _PATH1,INOUT char* _newinodePATH)
{
    char           _PATH[60];
    char*           lasttok;
    char*           temp;
    char            parentPATH[60]="/";
    i_node*         node;

    if(_PATH1==0)
    {
        return 0;/*NO PATH WAS PROVIDED*/
    }
    strcpy(_PATH,_PATH1);
    temp=strtok(_PATH," ");
    if(!(temp))
    {
        return 0;/*NO PATH WAS PROVIDED*/
    }
    temp=strtok(_PATH,"/");
    while(temp)
    {
        lasttok=temp;
        temp=strtok(NULL,"/");/*finde the last part of PATH*/
        if(temp!=0)
        {
           strcat(parentPATH,lasttok);
           strcat(parentPATH,"/");
        }
    }
    strcpy(_newinodePATH,lasttok);
    /*need to find the parent i node checking is the path exist*/
    if((node=VFS_LookupEntry(root,parentPATH)))
    {
        return node;
    }
    return 0;
}

inode_Err VFS_mkdir(char* _PATH1)
{
    inode_Err           err;
    char                name[30];
    char               _PATH[60];/*I need overwrit PATH string that it could be separated*/
    i_node*             parnt;
    i_node*             node;
    strcpy(_PATH,_PATH1);
    /*Find the parent directory*/
    /*Tokenize _PATH in 2 parts* to find parent and newname*/
    parnt=VFS_PATHpreparing(_PATH,INOUT name);
    if(parnt==0)
    {
        return VFS_PARENT_DIRECTORY_NOT_FOUND;
    }
    if(parnt->mode!=VFS_DERECTORY)
    {
        printf("\nPATH NOT EXISTS\n");
        return VFS_PATH_NOT_EXISTS;
    }

    /*need checking is the directory with same allready exist*/
    if(VFS_LookInSubdirect(parnt->i_n_blk,name))
    {
        printf("\nFile with same name already exists\n");
        return VFS_MKDIR_DIRECTORY_ALREADY_EXIST;
    }

    node=VFS_CreateInodes(name,VFS_DERECTORY,parnt,&err);/*Also and update parent*/
    if(node==0)
    {
        return VFS_FILE_CREATION_PROBLEMS;
    }
    err=VFS_Insert2Parent(parnt->i_n_blk,&node);
    if(err)
    {
        return err;
    }
    err=VFS_UpdateParentDirectory(parnt);
    return err;
}



inode_Err VFS_Create()
{
    inode_Err       err1;
    root=VFS_CreateBaseinodeData("/");
    root->mode=VFS_DERECTORY;
    root->permision=0xFFFF;
    /*Initiallizing of global*/
    strcpy(CWD_PATH,root->i_Filename);
    CWD_inode=root;
    err1=VFS_I_Blockcreate((i_node*)Heap,root,root->mode);/*Accept parent node (for root i_node - the parent
                                                           is Heap, and new node*/
    if(err1)
    {
        return err1;/*The inderection blockes not created*/
    }
    return 0;
}


indPtr VFS_FindPTR(indPtr _indPTR,ind_lvl _level,char* subPATH)
{
    indPtr temp;
    size_t    i=0;

    if(_level==0)/*Works on  Datalevel*/
    {
        for(i=0;i<I_N_BLOCKS;++i)
        {
            if( _indPTR[i] )/*every (_indPTR)[i] has void* level or (i_node*) level*/
            {
                if(!(strcmp(((i_node*)_indPTR[i])->i_Filename,subPATH)))
                {
                     return &( _indPTR[i]);
                }
            }
        }

        return 0;/*there are no name match on this direction*/
    }

    for(i=0;i<I_N_BLOCKS;++i)
    {

        temp=VFS_FindPTR(_indPTR[i],_level-1,subPATH);/*To down by one level*/

        if(temp==0)/*If temp==0 the empty cell will be in next block*/
        {
            continue;
        }
        if (*temp)
        {
            return temp;/*adress or pointer to void* ore i_node*/
        }
    }
    printf("Directory not found!!!!!!!!!!\n");
    return 0;/*ALl possible levels was checked any data can't be added */
}

i_node* VFS_LookInSubdirect(I_Block*_blk, char* subPATH)
{
    indPtr    ptr=0;
    size_t          i;/* I want to find Inder pointer to i_node with same name*/
   for(i=0;i<I_N_LEVELS;++i)/*From direct to tripple undirect*/
   {
       if((_blk->N_directArr)[i])
       {
           ptr=VFS_FindPTR((_blk->N_directArr[i]),i,subPATH);/*Recurcivey checks name*/
           if(ptr)
            {
                    return *ptr;/*Local*/
            }
       }
   }
   return 0; /* Folder not found*/
}

/*need find the node according to PATH if its not exist return null*/
i_node* VFS_LookupEntry(i_node* _node,char* _PATH)
{
    /*need to tokenise the PATH*/
    char     buf[100];
    char*    subPATH;
    i_node*  temp;
    strcpy(buf,_PATH);

    subPATH=strtok(buf," ");/*Now we get the start of path*/
    /*check is the 1st initial path directory is root*/
    if(*subPATH=='/')
    {
        subPATH=strtok(buf,"/");
        _node=root;
    }
    if(subPATH==0)/*THe desired node is root*/
    {
        return _node;
    }
    while(subPATH!=0)/* searches for i_node*/
    {
        /*pointer to next directory  if not existed temp==0*/
        temp=VFS_LookInSubdirect(_node->i_n_blk,subPATH);
        _node=temp;
        subPATH=strtok(NULL,"/");
    }
    if(_node==0)
    {
        printf("\nTHE PATH for new Directory not exists\n");
    }
    return _node;
}





#ifdef unitest_VFS_System
void regression_test(void);
void printnode(i_node* _node);
int unitest_VFS_Create(void);
int unitest_VFS_mkdir_and_LookupEntry();
int unitest_VFS_Getpos();
int unitest_VFS_openfile();
int unitest_VFS_write();
int unitest_VFS_read();
int unitest_VFS_ln();

int main()
{
    regression_test();
    return 0;

}

void regression_test()
#define is_success(x)  x?  "failed":"success"
{
    inode_Err   err1;
    inode_Err   err2;
    inode_Err   err3;
    inode_Err   err4;
    inode_Err   err5;
    inode_Err   err6;
    inode_Err   err7;
    inode_Err   err8;



    printf("START TESTING OF VFS_Create\n");
    err1=unitest_VFS_Create();
    printf("The VFS_Create is : %s \n",     is_success(err1));

    printf("\nSTART TESTING OF VFS_mkdir\n");
    err2=unitest_VFS_mkdir_and_LookupEntry();
    printf("\nThe TEST of VFS_mkdir_and_LookupEntry is : %s \n",      is_success(err2));


    printf("\nSTART TESTING OF VFS_Getpos\n");
    err3=unitest_VFS_Getpos();
    printf("\nThe VFS_Getpos is : %s \n",is_success(err3));

    printf("\nSTART TESTING OF VFS_openfile\n");
    err4=unitest_VFS_openfile();
    printf("\nThe VFS_openfile is : %s \n",is_success(err4));


    printf("\nSTART TESTING OF unitest_VFS_write\n");
    err5=unitest_VFS_write();
    printf("\nThe VFS_write is :                            %s \n",is_success(err5));

    printf("\nSTART TESTING OF unitest_VFS_read\n");
    err6=unitest_VFS_read();
    printf("\nThe VFS_read is :                             %s \n",is_success(err6));

    printf("\nSTART TESTING OF unitest_VFS_ln\n");
    err7=unitest_VFS_ln();
    printf("\nThe VFS_ln is :                               %s \n",is_success(err7));

    printf("\nSTART TESTING OF unitest_VFS_remove\n");
    err8=unitest_VFS_remove();
    printf("\nThe VFS_remove is :                           %s \n",is_success(err8));



    printf("The VFS_Create is :                           %s \n",is_success(err1));
    printf("\nThe TEST of VFS_mkdir_and_LookupEntry is :    %s \n",is_success(err2));
    printf("\nThe VFS_Getpos is :                           %s \n",is_success(err3));
    printf("\nThe VFS_openfile is :                         %s \n",is_success(err4));
    printf("\nThe VFS_write is :                            %s \n",is_success(err5));
    printf("\nThe VFS_read is :                             %s \n",is_success(err6));
    printf("\nThe VFS_ln is :                               %s \n",is_success(err7));
    printf("\nThe VFS_remove is :                           %s \n",is_success(err8));

    return;
}

int unitest_VFS_Create()
{
    int      i;
    indPtr      ptr;
    /*Init of global*/
    fdcounter=0;
    for(i=0;i<fdcounter;++i,fdlist[i]=0);
    Heap=MM_Create(64*1024,8);

    VFS_Create();
    ptr=(root->i_n_blk->N_directArr[0]);
    if (ptr[0]==Heap && ptr[1] == root)
    {
        printnode(root);
    }
    MM_Destroy(Heap);
    return 0;
}

int unitest_VFS_mkdir_and_LookupEntry()
{
    i_node* test;
    char    path[60];
    size_t  i;

    for(i=0;i<fdcounter;++i,fdlist[i]=0);
    Heap=MM_Create(64*1024,8);

    VFS_Create();

    VFS_mkdir("/Direct_home1");/*ok*/
    printnode(root);

    VFS_mkdir("/Direct_home2/New1");/*Path not found*/
    printnode(root);

    VFS_mkdir("/Direct_home2");/*ok*/
    printnode(root);

    VFS_mkdir("/Direct_home2/New2");/*ok*/
    printnode(root);

    VFS_mkdir("/Indirect_home3");/*ok*/
    VFS_mkdir("/Indirect_home4");/*ok*/
    printnode(root);
    VFS_mkdir("/Indirect_home5");/*folder capacity full*/
    VFS_mkdir("/Direct_home2/New2/Indirect_home6");/*ok*/
    VFS_mkdir("/Indirect_home6");/*folder capacity full ok*/

    puts("\nmkdir FINIDING BY PATH:\n");

    test=VFS_PATHpreparing("/Direct_home2",INOUT path);
    test=VFS_LookInSubdirect(test->i_n_blk,path);
    printnode(test);

    test=VFS_PATHpreparing("/Direct_home2/New2",INOUT path);
    test=VFS_LookInSubdirect(test->i_n_blk,path);
    printnode(test);


    test=VFS_PATHpreparing("/Direct_home2/New2/Indirect_home6",INOUT path);
    test=VFS_LookInSubdirect(test->i_n_blk,path);
    printnode(test);
     printcontent(root);
     MM_Destroy(Heap);
    return 0 ;
}

int unitest_VFS_Getpos()
{
    i_node**     node;
    int          i;

    for(i=0;i<fdcounter;++i,fdlist[i]=0);
    Heap=MM_Create(64*1024,8);

     VFS_Create();
     VFS_mkdir("/usr");
     VFS_mkdir("/Direct_home1");
     VFS_mkdir("/Direct_home2");
     VFS_mkdir("/Direct_home3");
     VFS_mkdir("/Direct_home4");
     VFS_mkdir("/Direct_home5");

    printf("\nTESTING OF POSITION\n\n");
    printnode(root);
    node=(i_node**)VFS_Getpos(root,0);
    printnode(*node);
    node=(i_node**)VFS_Getpos(root,1);
    printnode(*node);
    node=(i_node**)VFS_Getpos(root,2);
    printnode(*node);
    node=(i_node**)VFS_Getpos(root,3);
    printnode(*node);
    node=(i_node**)VFS_Getpos(root,4);
    printnode(*node);
    node=(i_node**)VFS_Getpos(root,5);
    printnode(*node);
    node=(i_node**)VFS_Getpos(root,6);
    if(node==0 && I_N_PAGESIZE<=8 && I_N_LEVELS<=2)
    {
        MM_Destroy(Heap);
        return 0;
    }

    if(node!=0 && I_N_PAGESIZE>=8 && I_N_LEVELS>=2)
    {
        MM_Destroy(Heap);
        return 0;
    }
    return 1;
}

int unitest_VFS_openfile()
{
    i_node* test;
    char    path[60];
    int          i;
    for(i=0;i<fdcounter;++i,fdlist[i]=0);
    Heap=MM_Create(64*1024,8);

    VFS_Create();

    openfile("/File_home1",S_READ);
    openfile("/Direct_home1/File_home1",S_READ);
    VFS_mkdir("/Direct_home1");
    test=VFS_PATHpreparing("/Direct_home1/File_home1",INOUT path);
    test=VFS_LookInSubdirect(test->i_n_blk,path);
    if(test==0)
    {
        printnode(test);
        if((openfile("/Direct_home1/File_home1",S_READ)))/* the 1st file descriptor is 0*/
        {
            test=VFS_PATHpreparing("/Direct_home1/File_home1",INOUT path);
            test=VFS_LookInSubdirect(test->i_n_blk,path);
            MM_Destroy(Heap);
            return 0;

        }
    }
    return 1;

}

int unitest_VFS_write()
{
    i_node*    node;
    i_node**   test;

    FILE*      fp;

   /* int        i;

    fdcounter=0;
    for(i=0;i<fdcounter;++i,fdlist[i]=0);
    Heap=MM_Create(64*1024,8);

    VFS_Create();
    printnode(root);

    VFS_mkdir("/Direct_home1");
    openfile("/Direct_home1/File_home1",S_READ);
    node=fdlist[fdcounter-1]->node;
    printnode(node);
    test=(i_node**)node->i_n_blk->N_directArr[0];

    char  buffer []="1";
    char  buffer1[]="2";
    char  buffer2[]="3";
    char  buffer3[]="4";
    char  buffer4[]="5";
    char  buffer5[]="6789ABC";


    printnode(node);
    int err=VFS_write(0,1,buffer);
    printnode(node);

    err=VFS_write(0,1,buffer1);

    err=VFS_write(0,1,buffer2);
    printnode(node);

    err=VFS_write(0,1,buffer3);
    printnode(node);

    err=VFS_write(0,1,buffer4);
    printnode(node);

    err=VFS_write(0,7,buffer5);
    printnode(node);
    if(fdlist[fdcounter-1]->pos==12)
    {
         printnode(node);
        MM_Destroy(Heap);
         return 0;
    }

    printf("\n\n WRITING FROM FILE\n\n");


    Htf_t* errhash=0;


    Htf_t* Hash=Hash_Tcreat(N,hash);

    /*Setting Pairs to table for case when allocated enought space to store them *
    fp=fopen(flen,"r");
    while(1)
    {
        fgets(name,100,fp);
        if(feof(fp))
        {
            break;
        }
        name[strlen(name)-1]='\0';

        fgets(number,100,fp);
        if(feof(fp))
        {
            break;
        }
        number[strlen(number)-1]='\0';
        Hash_Tset(Hash,name,number);
        ++i;
    }
    fclose(fp);




    return 1;*/
}


int unitest_VFS_read()
{
    i_node*    node;
    i_node**   test;
    int        i;

    fdcounter=0;
    for(i=0;i<fdcounter;++i,fdlist[i]=0);
    Heap=MM_Create(64*1024,8);
    VFS_Create();
    VFS_mkdir("/Direct_home1");
    openfile("/Direct_home1/File_home1",S_READ);
    node=fdlist[fdcounter-1]->node;
    test=(i_node**)node->i_n_blk->N_directArr[0];
    char  buffer []="1";
    char  buffer1[]="2";
    char  buffer2[]="3";
    char  buffer3[]="4";
    char  buffer4[]="5";
    char  buffer5[]="6789ABC";
    char  buffer6[13];

    int err=VFS_write(0,1,buffer);
    err=VFS_write(0,1,buffer1);
    err=VFS_write(0,1,buffer2);
    err=VFS_write(0,1,buffer3);
    err=VFS_write(0,1,buffer4);
    err=VFS_write(0,7,buffer5);

    fdlist[fdcounter-1]->pos=0;
    if(!VFS_read(0,12,buffer6))
    {
        printf("\n readed from i_node : %s \n",buffer6);
        return 0;
    }
    return 1;
}



int unitest_VFS_ln()
{
    i_node*    node;
    i_node**    node1;
    i_node**    node2;
    int        i;
    char       path[PATH];

    fdcounter=0;
    for(i=0;i<fdcounter;++i,fdlist[i]=0);
    Heap=MM_Create(64*1024,8);
    VFS_Create();
    VFS_mkdir("/Direct_home1");
    VFS_mkdir("/Direct_home1/Level2");
    openfile("/Direct_home1/File_home1",S_READ);
    VFS_ln(VFS_HLINK,"/Direct_home1/File_home1","/Direct_home1/Level2/HD_TO_File_home1");

    node1=(i_node**)VFS_Getpos(root,2);
    printnode(*node1);



    node=VFS_PATHpreparing("/Direct_home1/File_home1/",INOUT path);
    node=VFS_LookInSubdirect(node->i_n_blk,path);
    printnode(node);

    node=VFS_PATHpreparing("/Direct_home1/Level2/HD_TO_File_home1",INOUT path);
    node=VFS_LookInSubdirect(node->i_n_blk,path);
    printnode(node);


    printf("root Folder :\n");
    printcontent(*node1);

    node=VFS_PATHpreparing("/Direct_home1/Level2",INOUT path);
    node=VFS_LookInSubdirect(node->i_n_blk,path);
    printf("/Direct_home1/Level2/ :\n");
    printcontent(node);
    MM_Destroy(Heap);
    return 0;
}

int unitest_VFS_remove(char* _PATH)
{
    i_node*    node;
    i_node**    node1;
    i_node**    node2;
    int        i;
    char       path[PATH];

    fdcounter=0;
    for(i=0;i<fdcounter;++i,fdlist[i]=0);
    Heap=MM_Create(64*1024,8);
    VFS_Create();

    printf("\n/*Remove Empty last directory*/\n");
    VFS_mkdir("/Direct_home1");
    VFS_mkdir("/Direct_home1/Level2");

    node=VFS_PATHpreparing("/Direct_home1",INOUT path);
    node=VFS_LookInSubdirect(node->i_n_blk,path);
    printf("/Direct_home1 :\n");
    printcontent(node);
    VFS_remove("/Direct_home1/Level2");
    printf("\n__After remove /Direct_home1 :\n");
    printcontent(node);

    printf("\n/*/*Remove Empty non last directory*/*/\n");
    VFS_mkdir("/Direct_home1/Level2");
    VFS_mkdir("/Direct_home1/Level3");
    node=VFS_PATHpreparing("/Direct_home1",INOUT path);
    node=VFS_LookInSubdirect(node->i_n_blk,path);
    printf("/Direct_home1 :\n");
    printcontent(node);
    node1=(i_node**)VFS_Getpos(node,2);
    node2=(i_node**)VFS_Getpos(node,3);

    VFS_remove("/Direct_home1/Level2");
    printf("\n__After remove /Direct_home1 :\n");

    node=VFS_PATHpreparing("/Direct_home1",INOUT path);
    node=VFS_LookInSubdirect(node->i_n_blk,path);
    printcontent(node);

    printf("\n/*/*Insert next time after removing*/*/\n");
    VFS_mkdir("/Direct_home1/Level2");
    node=VFS_PATHpreparing("/Direct_home1",INOUT path);
    node=VFS_LookInSubdirect(node->i_n_blk,path);
    printcontent(node);



    /*Test produce the link to file and remove file after that link */
    printf("\n\n/*/*Testing delete files*/*/\n");
    printf("\n/*/*Initial codition*/*/\n");
    openfile("/Direct_home1/File_home1",S_READ);
    VFS_ln(VFS_HLINK,"/Direct_home1/File_home1","/Direct_home1/Level2/HD_TO_File_home1");
    VFS_mkdir("/Direct_home1/Direct_home2");

    node=VFS_PATHpreparing("/Direct_home1",INOUT path);
    node=VFS_LookInSubdirect(node->i_n_blk,path);
    printcontent(node);

    printf("\n/*/*Removing of File_home1 (but its HD_link :\n\
     /Direct_home1/Level2/HD_TO_File_home1 exists*/*/\n");
    VFS_remove("/Direct_home1/File_home1");
    printcontent(node);

    printf("\nFolder /Direct_home1/Level2/ content\n");
    node=VFS_PATHpreparing("/Direct_home1/Level2",INOUT path);
    node=VFS_LookInSubdirect(node->i_n_blk,path);
    printcontent(node);

    printf("\nFolder After remove of HD_TO_File_home1\n");
    VFS_remove("/Direct_home1/Level2/HD_TO_File_home1");
    node=VFS_PATHpreparing("/Direct_home1/Level2/",INOUT path);/*Has to print 2 folders only /Direct_home1/Level2/*/
    node=VFS_LookInSubdirect(node->i_n_blk,path);
    printcontent(node);

    return 0;
}

void printnode(i_node* _node)
{
    i_node*      ptr;
    if(_node==0)
    {
        return;
    }

    if(_node==(i_node*)Heap)
    {
        printf("\n\n!!!!!!!!!!!!!The  Node is HEAP!!!!!!!!!!!!!!!\n\n");
        return;
    }
    printf("\nThe type of i_node :  %d .(0--Directory,1--File,4--H_link) ",_node->mode);
    printf("\nNode name : %s ",_node->i_Filename);
    if((_node->i_n_blk->N_directArr[0])!=0)
    {
        ptr=(i_node*)(_node->i_n_blk->N_directArr[0])[0];
        if(_node->mode==VFS_DERECTORY)
        {
            if(ptr==(i_node*)Heap)
            {
                    printf("\nNode Parent name is Heap ");
            }
            else
            {
                printf("\nNode Parent name is :  %s", ptr->i_Filename);
            }
        }
    }
    else {return;}
    if(_node->mode==VFS_DERECTORY)
    {
        if((_node->i_n_blk->N_directArr[0])[1]!=0)
        {
            ptr=(i_node*)((_node->i_n_blk->N_directArr[0][1]));
            printf("\nNode  name of itself  : %s ",ptr->i_Filename);
        }
        else {return;}
    }

    printf("\nSize of i_node  : %d",_node->i_n_blk->sizeData);
    printf("\nLink_count of i_node  :%d \n",_node->i_n_blk->Link_count);
}

void printcontent(i_node* _node)
{
    i_node** temp;
    int      i;
    for(i=0;i<_node->i_n_blk->numofptr;++i)
    {
        temp=(i_node**)VFS_Getpos(_node,i);
        if ((void*)*temp==Heap)
        {
            printf("\n\n/Heap\n  ");
        }
        else
        {
            printf("\n      %s\n     ",(*temp)->i_Filename);
        }
    }
}

#endif /*unitest_VFS_System*/






